﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace Hellquest
{
    public enum ForceFieldType
    {
        Force,
        Vortex,
        Wind,
    }

    public class ForceField : Component
    {
        public ForceFieldType Type;

        public float Strength;
        public float MaxDistance = 0;

        public float Noise { get { return noise; } set { noise = MathHelper.Clamp(value, 0, 1); } }
        private float noise;

        public ForceField()
        {
            Strength = 1;
            noise = 0;
            Type = ForceFieldType.Force;
        }

        public ForceField(ForceFieldType _type, float _strength, float _maxDistance, float _noise)
        {
            Type = _type;
            Strength = _strength;
            MaxDistance = _maxDistance;
            Noise = _noise;
        }

        public override void OnAdd(GameObject _gameObject)
        {
            base.OnAdd(_gameObject);
            PhysicsEngine.Instance.AddForceField(this);
        }

        public override void OnRemove()
        {
            base.OnRemove();
            PhysicsEngine.Instance.RemoveForceField(this);
        }

        public Vector2 GetForceForPosition(Vector2 _position)
        {
            Vector2 forceDir = Vector2.Zero;

            switch (Type)
            {
                case ForceFieldType.Force:
                    forceDir = -(Position - _position);
                    break;

                case ForceFieldType.Vortex:
                    forceDir = Position - _position;
                    forceDir = Vector2.Transform(forceDir, Matrix.CreateRotationZ((0)));
                    break;

                case ForceFieldType.Wind:
                    forceDir = Vector2.Transform(new Vector2(1, 0), Matrix.CreateRotationZ(gameObject.transform.Rotation));
                    break;
            }

            float length = (Position - _position).Length();
            forceDir.Normalize();
            length = MathHelper.Clamp(length, 0, MaxDistance);


            if (MaxDistance == 0)
                return forceDir * (Strength + Strength * (Noise * (float)(MathUtils.Random.NextDouble() * 2 - 1)));
            else
                return forceDir * ((MaxDistance - length) / MaxDistance) * (Strength + Strength * (Noise * (float)(MathUtils.Random.NextDouble() * 2 - 1)));
        }
    }
}
